package org.starsource.forum.server.domain;

import java.io.Serializable;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.starsource.forum.client.domain.CategoryObject;
import org.starsource.forum.client.domain.SessionObject;
import org.starsource.forum.client.domain.UserObject;
import org.starsource.forum.client.util.Assertion;


public class Session implements HasId, Serializable {

	private static final long serialVersionUID = 6665080505698486303L;

	private static org.apache.log4j.Logger logger = org.apache.log4j.LogManager
	.getLogger(Session.class.getName());
	
	private int id;
	
	private ForeignKey<User> owner = new ForeignKey<User>();
	
	private String title;
	
	private ForeignKey<Category> category = new ForeignKey<Category>();

	private Timestamp createTimestamp;
	
	private Timestamp updateTimestamp;
	
	private Set<Message> messages = new HashSet<Message>();
	
	public Session() {
		
	}
	
	public Session(User owner, String title, Category category, Timestamp createTimestamp, Timestamp updateTimestamp) {
		this.setOwner(owner);
		this.title = title;
		this.setCategory(category);
		this.createTimestamp = createTimestamp;
		this.updateTimestamp = updateTimestamp;
	}

	public Session(int id, User owner, String title, Category category, Timestamp createTimestamp, Timestamp updateTimestamp) {
		this.id = id;
		this.setOwner(owner);
		this.title = title;
		this.setCategory(category);
		this.createTimestamp = createTimestamp;
		this.updateTimestamp = updateTimestamp;
	}

	@Override
	public boolean equals(Object obj) {
		try {
			Session object = (Session)obj;
			
			logger.debug("comparing session + " + this.id + " and session " + object.id);
			if (this.id != object.getId()) {
				logger.debug("this.id = " + this.id + " obj.id=" + object.id);
				return false;
			}
			
			if (this.getOwnerId() != object.getOwnerId()) {
				logger.debug("this.ownerId = " + this.owner.getId() + " obj.ownerId = " + object.owner.getId());
				return false;
			}
			
			if (!Assertion.isEqual(this.title, object.title)) {
				logger.debug("this.title = " + this.title + " obj.title = " + object.title);
				return false;
			}
			if (this.getCategoryId() != object.getCategoryId()) {
				logger.debug("this.categoryId = " + this.category.getId() + " obj.categoryId = " + object.category.getId());
				return false;
			}
			if (!Assertion.isEqual(this.createTimestamp, object.createTimestamp)) {
				logger.debug("this.createTimestamp = " + this.createTimestamp + " obj.createTimestamp = " + object.createTimestamp);
				return false;
			}
			if (!Assertion.isEqual(this.updateTimestamp, object.updateTimestamp)) {
				logger.debug("this.updateTimestamp = " + this.updateTimestamp + " obj.updateTimestamp = " + object.updateTimestamp);
				return false;
			}
			
			logger.debug("WOW, session equals");
			return true;
		} catch (Exception e) {
			logger.error("exception, stop comparation");
			return false;
		}
	}
	
	public int getId() {
		return this.id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public User getOwner() {
		return this.owner.getObject();
	}
	
	public void setOwner(User owner) {
		this.owner.setObject(owner);
	}
	
	public int getOwnerId() {
		return this.owner.getId();
	}
	
	public void setOwnerId(int id) {
		this.owner.setId(id);
	}
	
	public Timestamp getCreateTimestamp() {
		return this.createTimestamp;
	}
	
	public void setCreateTimestamp(Timestamp createTimestamp) {
		this.createTimestamp = createTimestamp;
	}
	
	public Timestamp getUpdateTimestamp() {
		return this.updateTimestamp;
	}
	
	public void setUpdateTimestamp(Timestamp updateTimestamp) {
		this.updateTimestamp = updateTimestamp;
	}
	
	public String getTitle() {
		return this.title;
	}
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public Category getCategory() {
		return this.category.getObject();
	}
	
	public void setCategory(Category category) {
		this.category.setObject(category);
	}
	
	public int getCategoryId() {
		return this.category.getId();
	}
	
	public void setCategoryId(int categoryId) {
		this.category.setId(categoryId);
	}
	
	public Set<Message> getMessages() {
		return this.messages;
	}
	
	public void setMessages(Set<Message> messages) {
		this.messages = messages;
	}

	public Date getCreateDate() {
		return new Date(this.createTimestamp.getTime());
	}
	
	public Time getCreateTime() {
		return new Time(this.createTimestamp.getTime());
	}
	
	public SessionObject getSessionObject() {
		UserObject user = null;
		if (this.owner.getObject() != null) user = this.owner.getObject().getUserObject(); 
		
		CategoryObject category = null;
		if (this.category.getObject() != null) category = this.category.getObject().getCategoryObject(null); 

		return new SessionObject(this.id, user, this.title, category, this.createTimestamp, this.updateTimestamp);
	}
	
	public SessionObject getSessionObjectWithMessage() {
		logger.debug("GETTING SESSION: ID:" + this.id + " TITLE:" + this.title);
		SessionObject sessionObject = this.getSessionObject();
		
		Iterator<Message> messages = this.messages.iterator();
		while (messages.hasNext()) {
			Message message = messages.next();
			logger.debug("adding message_id:" + message.getId());
			sessionObject.getMessages().add(message.getMessageObject(sessionObject));
		}
		return sessionObject;
	}
	
}
